package org.fujay.langchain4jserver.infrastructure.persistence.assembler;

import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.fujay.langchain4jserver.domain.model.aggregate.Model;
import org.fujay.langchain4jserver.domain.model.vo.*;
import org.fujay.langchain4jserver.infrastructure.persistence.mybatis.entity.ModelPo;

/**
 * 模型聚合 与 持久化对象 之间的转换器
 */
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class ModelAssembler {

    /**
     * 将持久化对象转换为领域聚合根
     *
     * @param po ModelPO
     * @return Model Aggregate
     */
    public static Model toAggregate(final ModelPo po) {
        if (po == null) {
            return null;
        }

        ModelId modelId = new ModelId(po.getId());
        ModelType modelType = ModelType.fromName(po.getModelType());

        SupplierInfo supplierInfo = new SupplierInfo(po.getModelSupplier(), po.getSupplierName());

        ModelConfig modelConfig =
                ModelConfig.builder()
                        .responseFormat(po.getResponseFormat())
                        .baseUrl(po.getBaseUrl())
                        .apiKey(po.getApiKey())
                        .secretKey(po.getSecretKey())
                        .temperature(po.getTemperature())
                        .topK(po.getTopK())
                        .topP(po.getTopP())
                        .maxTokens(po.getMaxTokens())
                        .numCtx(po.getNumCtx())
                        .timeOut(po.getTimeOut())
                        .maxRetries(po.getMaxRetries())
                        .maxMemory(po.getMaxMemory())
                        .logRequests(po.getLogRequests())
                        .logResponses(po.getLogResponses())
                        .build();

        TestResult testResult = TestResult.fromCode(po.getLastTestStatus());
        ConnectionStatus connectionStatus = new ConnectionStatus(po.getLastTestTime(), testResult);

        return Model.load(
                modelId,
                po.getModelName(),
                modelType,
                supplierInfo,
                modelConfig,
                po.isEnabled(),
                connectionStatus,
                po.getCreateTime(),
                po.getUpdateTime());
    }

    /**
     * 将领域聚合根转换为持久化对象
     *
     * @param model Model Aggregate
     * @return ModelPO
     */
    public static ModelPo toPO(final Model model) {

        ModelPo po = new ModelPo();
        po.setId(model.getId().value());
        po.setModelName(model.getModelName());
        po.setModelType(model.getModelType().name());

        po.setModelSupplier(model.getSupplier().supplierCode());
        po.setSupplierName(model.getSupplier().supplierName());

        ModelConfig config = model.getConfig();
        po.setResponseFormat(config.responseFormat());
        po.setBaseUrl(config.baseUrl());
        po.setApiKey(config.apiKey());
        po.setSecretKey(config.secretKey());
        po.setTemperature(config.temperature());
        po.setTopK(config.topK());
        po.setTopP(config.topP());
        po.setMaxTokens(config.maxTokens());
        po.setNumCtx(config.numCtx());
        po.setTimeOut(config.timeOut());
        po.setMaxRetries(config.maxRetries());
        po.setMaxMemory(config.maxMemory());
        po.setLogRequests(config.logRequests());
        po.setLogResponses(config.logResponses());

        po.setEnabled(model.isEnabled());

        ConnectionStatus status = model.getConnectionStatus();
        po.setLastTestStatus(status.lastTestResult().getCode());
        po.setLastTestTime(status.lastTestTime());

        return po;
    }
}
